home *** CD-ROM | disk | FTP | other *** search
- /*====================================================
- ARTemis
- (version 1.3)
- FM-TOWNS 用ペイントツール
-
- by 松内 良介 1994
- ====================================================*/
- #define MODULE_IMGWIN
- /*
- imgwins.c
-
- int imageWINfunc(kobj, messId, argc, pev, trigger)
- int imageSBARfunc(kobj, messId, argc, pev, trigger)
- int ImageEraseDBtnProc(int kobj)
-
- static int draw_line(IMWIN *win, POINT *first, int type)
- static int draw_freeline(IMWIN *win, POINT *first, int type)
- */
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <winb.h>
- #include <te.h>
- #include <fntb.h>
- #include <gui.h>
- #include <egb.h>
- #include <wgb.h>
- #include <msdos.cf>
- #include "art.h"
- #include "guisub.h"
- #include "wgbmac.H"
- #include "alert.h"
-
- #include "imagewin.h"
- #include "imgwin.h"
- #include "pensel.h"
- #include "colsel.h"
- #include "fifo.h"
- #include "subgrp.h"
- #include "desktop.h"
- #include "copy.h"
-
- int idImageWin = -1 ;
- int idImageHSBar = -1 ;
- int idImageVSBar = -1 ;
- int idImageTitleDBtn = -1 ;
- int idImageTitleMsg = -1 ;
- int idImageEraseDBtn = -1 ;
- int idImageBtn = -1 ;
-
- /*--------------------------------------------------------*/
- /* 部品の呼び出し関数 */
- /*--------------------------------------------------------*/
-
- static int draw_freeline(IMWIN *win, EVENT* first_ev, int type);
- static int draw_line(IMWIN *win, POINT *first, int type);
-
- /* ■画像ウィンドウの呼び出し関数■ */
-
- /* initDataIMGWIN:imageWIN:MJ_WINDOWL40の呼び出し関数 */
- int imageWINfunc(kobj, messId, argc, pev, trigger)
- int kobj ;
- int messId ;
- int argc ;
- EVENT *pev ;
- int trigger ;
- {
- IMWIN *win;
- WINCLIP *clipStack;
- win = imagewin_getWinFromPart(kobj);
- if (win == NULL)
- return -1;
-
- /* MM_SHOW メッセージへの応答 */
- if (messId == MM_SHOW)
- imagewin_updateScr(win);
-
- /* MM_UPDATE(リサイズ)への応答 */
- else if (messId == MM_UPDATE)
- imagewin_resize(win, TRUE);
-
- /* アクティブになった時 */
- else if (messId == MM_WAKE)
- {
- HYPER Ht;
- WINCLIP *clipStack;
- OBJHYP(win->titlebar).clr.back = DARKGRAY;
- OBJHYP(win->titlemsg).clr.ch = WHITE;
- OBJHYP(win->erasebtn).clr.back = DARKGRAY;
- WIN_beginUpDateObj(win->titlebar, &clipStack);
- MMI_SendMessage(win->titlebar, MM_SHOW, 0);
- MMI_SendMessage(win->titlemsg, MM_SHOW, 0);
- MMI_SendMessage(win->erasebtn, MM_SHOW, 0);
- WIN_endUpDateObj(clipStack);
- imagewin_setCurrentWin(win);
- }
-
- /* ノンアクティブになった時 */
- else if (messId == MM_SLEEP)
- {
- HYPER Ht;
- WINCLIP *clipStack;
- OBJHYP(win->titlebar).clr.back = GRAY;
- OBJHYP(win->titlemsg).clr.ch = BLACK;
- OBJHYP(win->erasebtn).clr.back = GRAY;
- WIN_beginUpDateObj(win->titlebar, &clipStack);
- MMI_SendMessage(win->titlebar, MM_SHOW, 0);
- MMI_SendMessage(win->titlemsg, MM_SHOW, 0);
- MMI_SendMessage(win->erasebtn, MM_SHOW, 0);
- WIN_endUpDateObj(clipStack);
- if (imagewin_getCurrentWin() == win)
- imagewin_setCurrentWin(NULL);
- }
-
- // マウスボタンに対する応答
- else if (messId == MM_MOUSEON && (pev->shift&SLEFTBTN) != 0)
- {
- int ret;
- int tool = toolbox_getCurrentTool();
- switch (tool)
- {
- case TOOL_FPSET:
- case TOOL_FLINE:
- case TOOL_KOSURI:
- case TOOL_PAINT:
- case TOOL_NIZIMI:
- case TOOL_BOKASI:
- case TOOL_SAND:
- ret = draw_freeline(win, pev, tool);
- break;
- case TOOL_LINE:
- ret = draw_line(win, (POINT*)&pev->info, 0);
- break;
- case TOOL_BOXFILL:
- ret = draw_line(win, (POINT*)&pev->info, 2);
- break;
- case TOOL_COPY:
- ret = input_rectarea(win, pev);
- break;
- case TOOL_POLYGONCOPY:
- ret = input_polygonarea(win,pev);
- break;
- case TOOL_POLYGONFILL:
- ret = cmd_polygonfill(win,pev);
- break;
- case TOOL_ZOOMCOPY:
- ret = cmd_rectzoomcopy(win,pev);
- break;
- }
- return ret;
- }
-
- else if (messId == MM_MOUSEON && (pev->shift&SRIGHTBTN) != 0)
- {
- // スポイト操作
- POINT mospt = *(POINT*)&pev->info;
- if (imagewin_PtInPic(win,&mospt))
- {
- POINT ptPic;
- imagewin_getPosFromMos(win,&mospt,&ptPic);
- PIXEL pix;
- pic_getPixelXy(win->pic, ptPic.x,ptPic.y, &pix);
- colsel_setCurPixel(&pix);
- }
- }
- return NOERR ;
- }
-
- /* ■画像ウィンドウのスクロールバー■ */
-
- /* initDataIMGWIN:imageSBARhori:MJ_SCRLL40の呼び出し関数 */
- /* initDataIMGWIN:imageSBARvert:MJ_SCRLL40の呼び出し関数 */
- int imageSBARfunc(kobj, messId, argc, pev, trigger)
- int kobj ;
- int messId ;
- int argc ;
- EVENT *pev ;
- int trigger ;
- {
- IMWIN *win;
- if ((win = imagewin_getWinFromPart(kobj)) == NULL)
- return -1;
- imagewin_updateBuf(win);
- imagewin_updateScr(win);
- return NOERR ;
- }
-
- int ImageEraseDBtnProc(int kobj)
- // initDataZIMGWIN:idImageEraseDBtn:MJ_DBUTTONL40の呼び出し関数
- {
- IMWIN *win;
- if ((win = imagewin_getWinFromPart(kobj)) == NULL)
- return -1;
- char buf[250];
- sprintf(buf, "画像 %s のウィンドウをクローズします。"
- "画像データは破棄されますが、よろしいですか?",
- (win->fname[0]==0 ? "<名称未定>" : win->fname));
- if (dispCheckMessage("画像ウィンドウを閉じる", buf, "続行") == 0)
- {
- imagewin_unlink(win);
- imagewin_destroy(win);
- if (imagewin_getCurrentWin() == win)
- imagewin_setCurrentWin(NULL);
- }
- return NOERR ;
- }
-
-
- /*--------------------------------------------------------*/
- /* 自由曲線による描画 */
- /*--------------------------------------------------------*/
-
- static int pen_ofsx, pen_ofsy;
-
- static void _putPixel(IMWIN *win, POINT *pt)
- /* 画像内の位置 pt に点を置く */
- {
- PIXEL pixel;
- colsel_getPixel(&pixel);
- pic_psetpen(win->pic,pt->x,pt->y,pensel_curpen(),&pixel);
- }
-
- static void _flushPointBuf(IMWIN *win, FIFO *points, int tooltype)
- {
- if (fifo_isEmpty(points))
- return;
- pic_beginUpDate(win->pic);
- /* 4座標ずつまとめて処理 */
- int i;
- for (i=0; i<4; i++)
- {
- if (fifo_isEmpty(points))
- break;
- POINT mosp, imgp;
- /* マウスカーソル位置が画像内のどこであるかを得る */
- fifo_get(points, &mosp);
- imagewin_getPosFromMos(win, &mosp, &imgp);
- PIXEL pixel; colsel_getPixel(&pixel);
- Pen pen = pensel_curpen();
- switch(tooltype)
- {
- case TOOL_NIZIMI:
- pic_blot(win->pic, imgp.x,imgp.y,2,paramNizimi, &pixel);
- break;
- case TOOL_KOSURI:
- pic_kosuriDrag(win->pic,imgp.x-pen_ofsx,imgp.y-pen_ofsy,
- paramKosuri);
- break;
- case TOOL_BOKASI:
- pic_diffusePen(win->pic,imgp.x,imgp.y,pen);
- break;
- case TOOL_SAND:
- pic_sandPen(win->pic,imgp.x,imgp.y,pen);
- break;
- default:
- _putPixel(win, &imgp);
- break;
- }
- }
- /* 画面(とユーザー領域バッファ)に画像の更新部分を転送 */
- FRAME updatefr;
- pic_endUpDate(win->pic, &updatefr);
- imagewin_updateScrPart(win, &updatefr);
- }
-
- static int draw_freeline(IMWIN *win, EVENT* first_ev, int type)
- /* first:最初のマウス座標 */
- {
- imagewin_storeUndo(win);
- EVENT *ev = first_ev;
- POINT cp = *(POINT*)&first_ev->info;
- POINT lastp = cp;
- // FIFOバッファの作成
- FIFO *points = fifo_new(sizeof(POINT));
- if (points == NULL)
- {
- dispAlertMessage("メモリ不足です",
- "描画処理を行うためのメモリ領域が不足しています。"
- "不要な画像ウィンドウをクローズしてみてください");
- return NOERR;
- }
- // 最初の点に関する処理
- switch(type)
- {
- case TOOL_KOSURI: {
- char *graypat; int wid,ht;
- pensel_getPattern(&graypat, &wid,&ht,&pen_ofsx,&pen_ofsy);
- POINT pt; imagewin_getPosFromMos(win, &cp, &pt);
- pic_kosuriStart(win->pic,pt.x-pen_ofsx,pt.y-pen_ofsy,
- graypat,wid,ht);
- } break;
- case TOOL_PAINT: {
- POINT pt; imagewin_getPosFromMos(win, &cp, &pt);
- PIXEL pix; colsel_getPixel(&pix);
- int csr;
- MG_PushPtr(MOSICON_WAIT, &csr);
- pic_beginUpDate(win->pic);
- pic_paint(win->pic,pt.x,pt.y, &pix);
- FRAME frUpdate;
- pic_endUpDate(win->pic, &frUpdate);
- MG_PopPtr(csr);
- imagewin_updateScrPart(win, &frUpdate);
- } break;
- }
- /* イベントループ */
- BOOL fFirst = TRUE;
- int ev_ret = NOERR;
- for (;;)
- {
- // マウスボタンが放されたら終了
- if (!fFirst && ev->what!=EVMOSDRAG && (ev->shift&SLEFTBTN)!=0)
- break;
- // PIC領域にカーソルがあれば、座標登録
- else if (imagewin_PtInPic(win, &cp))
- {
- /* FIFOバッファへ座標を登録する関数 */
- void push_p(int x,int y)
- {
- POINT p; p.x = x; p.y = y;
- fifo_set(points,&p);
- }
- /* 処理種別ごとに分岐 */
- switch (type)
- {
- case TOOL_KOSURI:
- case TOOL_NIZIMI:
- push_p(cp.x, cp.y);
- break;
- case TOOL_FPSET:
- case TOOL_BOKASI:
- case TOOL_SAND:
- if (ev_ret == NOERR)
- push_p(cp.x, cp.y);
- break;
- case TOOL_FLINE:
- if (ev_ret == NOERR)
- do_line_cont(lastp.x,lastp.y,cp.x,cp.y, push_p);
- break;
- }
- lastp = cp;
- }
- if (!fifo_isEmpty(points))
- _flushPointBuf(win,points,type);
- // イベントセンス
- MMI_iosense();
- EVENT *pre_ev = ev;
- if ((ev_ret = MMI_GetEvnt(EVMOSDRAG|EVMOSUP,&ev)) != NOERR)
- ev = pre_ev;
- else
- fFirst = FALSE;
- cp = *(POINT*)&ev->info;
- }
- /* 座標バッファのフラッシュ */
- while (!fifo_isEmpty(points))
- _flushPointBuf(win,points,type);
- fifo_destroy(points);
- /* 次に続くイベントループ処理のために、最後のイベントをキューに戻す */
- EVENT evbuf;
- evbuf = *ev;
- MMI_SetEvnt(&evbuf);
- return NOERR ;
- }
-
- /*--------------------------------------------------------*/
- /* 直線、矩形、矩形フィル */
- /*--------------------------------------------------------*/
-
- static int draw_line(IMWIN *win, POINT *first, int type)
- /* first:最初のマウス座標 */
- /* type:0=直線 1=矩形 2=矩形フィル */
- {
- imagewin_storeUndo(win);
- int ret;
- EVENT *ev, evbuf;
- WINCLIP *pstackClip ;
- FIFO *points;
- POINT lastp;
- int rub_x, rub_y;
- /* FIFOバッファの作成 */
- points = fifo_new(sizeof(POINT));
- lastp = *first;
- rub_x = lastp.x, rub_y = lastp.y;
- /* クリップ枠の設定 */
- RM_setOriginZero();
- RM_setClipWinUser(win->win, &pstackClip) ;
- /* イベントループ */
- for (;;)
- {
- int what,shift;
- POINT *pt;
- /* ラバー描画 */
- MG_mosDisp(2);
- if (type == 0)
- { WGB_LINE(guiEgbPtr,lastp.x,lastp.y,rub_x,rub_y,
- MG_colorChange(WHITE), 4); }
- else
- { WGB_BOXLINE(guiEgbPtr,lastp.x,lastp.y,rub_x,rub_y,
- MG_colorChange(WHITE), 4); }
- MG_mosDisp(3);
- /* イベントセンス */
- do {
- MMI_iosense();
- } while (MMI_GetEvnt(EVALL, &ev) != NOERR);
- /* ラバー消去 */
- MG_mosDisp(2);
- if (type == 0)
- { WGB_LINE(guiEgbPtr,lastp.x,lastp.y, rub_x, rub_y,
- MG_colorChange(WHITE), 4); }
- else
- { WGB_BOXLINE(guiEgbPtr,lastp.x,lastp.y, rub_x, rub_y,
- MG_colorChange(WHITE), 4); }
- MG_mosDisp(3);
- /* イベント種別、シフト状態、マウス座標を得る */
- what = ev->what;
- shift = ev->shift;
- pt = (POINT *) &ev->info;
- /* 次のラバー座標を得る */
- rub_x = pt->x;
- rub_y = pt->y;
- /* 左ボタンがクリックされたら */
- if (what == EVMOSDN && (shift & SLEFTBTN) != 0)
- {
- FRAME fr; RM_getWinUserFrame(win->win, &fr);
- if (fr.X <= pt->x && pt->x <= fr.X2 &&
- fr.Y <= pt->y && pt->y <= fr.Y2)
- {
- void pset(int x,int y)
- {
- POINT p; p.x = x; p.y = y;
- fifo_set(points,&p);
- }
- switch (type)
- {
- case 0:
- do_line(lastp.x,lastp.y,pt->x,pt->y, pset);
- while (!fifo_isEmpty(points))
- _flushPointBuf(win, points, TOOL_FPSET);
- break;
- case 1:
- do_boxline(lastp.x,lastp.y,pt->x,pt->y, pset);
- while (!fifo_isEmpty(points))
- _flushPointBuf(win, points, TOOL_FPSET);
- break;
- case 2:
- POINT mosp,imgp1,imgp2;
- FRAME updatefr,scrfr;
- PIXEL pixel;
- int min_y,max_y,i;
- colsel_getPixel(&pixel);
- mosp.x = lastp.x, mosp.y = lastp.y;
- imagewin_getPosFromMos(win, &mosp, &imgp1);
- mosp.x = pt->x, mosp.y = pt->y;
- imagewin_getPosFromMos(win, &mosp, &imgp2);
- min_y = _min(imgp1.y, imgp2.y);
- max_y = _max(imgp1.y, imgp2.y);
- /* 画面更新の開始 */
- MG_mosDisp(2);
- pic_beginUpDate(win->pic);
- /* 矩形の描画 */
- for (i=min_y; i<=max_y; i++)
- pic_grayhline(win->pic,imgp1.x,imgp2.x,i,
- pensel_getmix(),&pixel);
- /* 画面に画像の更新部分を転送 */
- pic_endUpDate(win->pic, &updatefr);
- imagewin_updateScrPart(win, &updatefr);
- /* 画面更新の終了 */
- MG_mosDisp(3);
- }
- lastp = *pt;
- if (type != 0)
- break;
- }
- }
- /* 右ボタンがクリックされたら */
- else if (what == EVMOSDN && (shift & SRIGHTBTN) != 0)
- {
- break;
- }
- }
- /* クリップ枠の復帰 */
- RM_resetClipWinUser(pstackClip) ;
- RM_recoverOrigin();
- /* FIFOバッファの消滅 */
- fifo_destroy(points);
- /* 次に続くイベントループ処理のために、マウス左ボタンの EVMOSUP イベントを
- キューに積む */
- evbuf = *ev;
- evbuf.what = EVMOSUP;
- evbuf.shift = (evbuf.shift & (~SRIGHTBTN)) | SLEFTBTN;
- MMI_SetEvnt(&evbuf);
- return NOERR ;
- }
-